// @algorithm @lc id=210 lang=cpp 
// @title course-schedule-ii


// @test(2,[[1,0]])=[0,1]
// @test(4,[[1,0],[2,0],[3,1],[3,2]])=[0,2,1,3]
// @test(1,[])=[0]
class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> dG(numCourses); // [course] --> [ next courses ... ]
        vector<int> indeg(numCourses, 0);
        for(auto & req : prerequisites){
            dG[ req[1] ].push_back( req[0] ); // req[1] --> req[0]
            indeg[ req[0] ]++;
        }

        queue<int> canLearn;
        for(int i=0; i<numCourses; i++)
            if(indeg[i]==0) canLearn.push(i);
        vector<int> ans;
        while(!canLearn.empty()){
            int fin = canLearn.front(); canLearn.pop();
            ans.push_back(fin);
            for(auto next : dG[fin])
                if(0 == --indeg[next])
                    canLearn.push(next);
        }
        if(ans.size() == numCourses) return ans;
        return {};
    }
};